﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using RoguelikeLib;

namespace RoguelikeUIWPF
{
    class Renderer : IRenderer
    {
        # region Fields
        public class RenderObject
        {
            public string Character { get; set; }
            public SolidColorBrush Color { get; set; }
        }

        private readonly Canvas _canvas;
        private TextBlock[][] _grid;
        Random _rng = new Random();
        private string[] _charactersArray = new string[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "." };
        private SolidColorBrush[] _colors = new SolidColorBrush[] {Brushes.Red, Brushes.Blue, Brushes.Purple, Brushes.Yellow, Brushes.Green};
        Dictionary<RObjects, RenderObject> rObjectsMap = new Dictionary<RObjects,RenderObject>()
                                                               {
                                                                   {RObjects.FireWall, new RenderObject(){Character = "#", Color = Brushes.Orange}},
                                                                   {RObjects.StoneWall, new RenderObject(){Character = "#", Color = Brushes.Gray}},
                                                                   {RObjects.StoneFloor, new RenderObject(){Character = ".", Color = Brushes.DeepPink}},
                                                                  {RObjects.GrassFloor, new RenderObject(){Character = ".", Color = Brushes.GreenYellow}},
                                                                  {RObjects.ClosedWoodenDoor, new RenderObject(){Character = "+", Color = Brushes.Brown}},
                                                                  {RObjects.ClosedIceDoor, new RenderObject(){Character = "+", Color = Brushes.Cyan}},
                                                                  {RObjects.ClosedFireDoor, new RenderObject(){Character = "+", Color = Brushes.OrangeRed}},
                                                                  {RObjects.StairsDown, new RenderObject(){Character = ">", Color = Brushes.White}},

                                                               };
        private int _tileWidth = 15;
        private int _tileHeight = 15;
        # endregion

        # region Properties

        public int Height
        {
            get { return 40; }
        }

        public int HeightInPixels
        {
            get { return Height * _tileHeight; }
        }

        public int Width
        {
            get { return 80; }
        }

        public int WidthInPixels
        {
            get { return Width * _tileWidth; }
        }

        # endregion

        # region Constructor

        public Renderer(Canvas canvas)
        {
            _canvas = canvas;
            CreateGrid();
        }

        # endregion

        # region Public Methods

        /// <summary>
        /// Clears the screen
        /// </summary>
        public void Clear()
        {
            for (int y = 0; y < Height; y++)
            {
                var row = new TextBlock[Width];
                _grid[y] = row;
                for (int x = 0; x < Width; x++)
                {
                    var textBlock = row[x];
                    textBlock.Text = "";
                }
            }
        }


        /// <summary>
        /// Creates the controls which we will be drawing on
        /// </summary>
        public void CreateGrid()
        {
            _grid = new TextBlock[Height][];
            for (int i = 0; i < Height; i++)
            {
                var row = new TextBlock[Width];
                _grid[i] = row;
                for (int j = 0; j < Width; j++)
                {
                    var textBlock = new TextBlock();
                    textBlock.Width = _tileWidth;
                    textBlock.Height = _tileHeight;
                    textBlock.Text = "";
                    textBlock.Foreground = _colors[0];
                    Canvas.SetLeft(textBlock, j*_tileWidth);
                    Canvas.SetTop(textBlock, i * _tileHeight);
                    row[j] = textBlock;
                    _canvas.Children.Add(textBlock);
                }
            }
        }

        /// <summary>
        /// Draws the given "thing" on the screen
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="thingToDraw"></param>
        public void Draw(int x, int y, RObjects thingToDraw)
        {
            var character = _charactersArray[_rng.Next(_charactersArray.Length)];
            var textBlock = _grid[y][x];
            var renderObject = rObjectsMap[thingToDraw];

            textBlock.Text = renderObject.Character;
            textBlock.Foreground = renderObject.Color;
        }

        /// <summary>
        /// Randomly update the map (Christmas lights!)
        /// </summary>
        public void UpdateGrid()
        {
            int x = _rng.Next(Width);
            int y = _rng.Next(Height);
            Draw(x, y, RObjects.GrassFloor);
        }

        # endregion

    }
}
